import _ from 'lodash'
import ebus from './ebus.js'
import Konva from 'konva'
import store from "../store/index.js"
import { mapState } from 'vuex'
var media = mapState(["media"])
// console.log(store.state.location.latitude)
console.log('media:', media)
console.log('state:', store.state)

var windowImg = new Image()
windowImg.src = require('../assets/img/vidbg.jpg')

var audioImg = new Image()
audioImg.src = require('../assets/img/audio.png')

var vedioImg = new Image()
vedioImg.src = require('../assets/img/vedio.png')

var cancelImg = new Image()
cancelImg.src = require('../assets/img/cancel.png')

export function LcdPreview() {
  this.init = function(container, cfg) {
    if (this.stage) {
      this.dftLayer = undefined
      this.stage.destroy()
    }

    this.stage = new Konva.Stage({
      container: container,
      width: cfg.width,
      height: cfg.height
    })

    this.width = cfg.width
    this.height = cfg.height
    this.scale = cfg.scale
    let layer = new Konva.Layer()
    this.stage.add(layer)
    this.dftLayer = layer
    this.stage.userdata = cfg
  }

  this.getUserCfg = function() {
    return this.stage.userdata
  }

  this.getLayer = function() {
    return this.dftLayer
  }

  this.addWindow = function(window, ratio) {
    let layer = this.getLayer()
    let coordinate = window.coordinate
    let windowWidth = coordinate.right - coordinate.left
    let windowHeight = coordinate.bottom - coordinate.top

    var group = new Konva.Group({
      x: coordinate.left * ratio.xScale,
      y: coordinate.top * ratio.yScale,
      name: 'window',
      draggable: false
    })
    layer.add(group)

    var attrs = {
      width: windowWidth * ratio.xScale,
      height: windowHeight * ratio.yScale,
      image: windowImg
    }
    var img = new Konva.Image(attrs)
    group.add(img)

    let dftFontSize = 12
    var showText = ``
    if (window.srcName) {
      showText += window.srcName
    }
    if (window.srcSetName) {      
      showText += window.srcSetName
    }
    var attrs = {
      width: windowWidth * ratio.xScale,
      y: (windowHeight * ratio.yScale - dftFontSize) / 2,
      text: showText,
      fill: '#000', //black
      align: 'center',
    }
    var text = new Konva.Text(attrs)
    group.add(text)
    
    img.on('click', e => {
      let layer = this.getLayer()
      window.srcName = store.state.media.srcName // 已取到这个值
      text.textArr[0].text = `${window.srcName}`

      layer.draw();
      ebus.emit('updata-src-name')
    })

    if (window.playAudio && window.srcName) {
      var attrs = {
        width: 20,
        height: 20,
        image: audioImg
      }
      var node = new Konva.Image(attrs)
      group.add(node)
    }

    if (window.playVedio && window.srcName) {
      var attrs = {
        x: 25,
        y: 0,
        width: 20,
        height: 20,
        image: vedioImg
      }
      var node = new Konva.Image(attrs)
      group.add(node)
    }

    if (window.skipSwitch) {
      var attrs = {
        width: 20,
        height: 20,
        image: cancelImg
      }
      var node = new Konva.Image(attrs)
      group.add(node)
    }
  }

  this.updateWindows = function(windows, ratio) {
    let stage = this.stage
    var groups = stage.find('.window')
    groups.each(function(group) {
      group.destroy()
    })

    let drawWindows = _.sortBy(windows, 'layer')

    _.forEach(drawWindows, function(window) {
      this.addWindow(window, ratio)
    }.bind(this))

    let layer = this.getLayer()
    layer.draw()
  }  

  this.updateBg = function(cfg) {
    var attrs = {
      x: 0,
      y: 0,
      width: this.width,
      height: this.height,
      fill: cfg.color.hex,
      name: 'bg'
    }
    let layer = this.getLayer()

    var bg = this.stage.find('.bg')[0]
    if (bg) {
      bg.setAttrs(attrs)
    } else {
      var node = new Konva.Rect(attrs)
      layer.add(node)
    }

    layer.draw()
  }

  this.updateBgImg = function(cfg) {
    let width = this.width
    let height = this.height
    let image = cfg.img
    let imageWidth = image.width * this.scale
    let imageHeight = image.height * this.scale
    var attrs = {
      x: 0,
      y: 0,
      width: width,
      height: height,
      image: image,
      name: 'bgImg'
    }
    let layer = this.getLayer()

    if (cfg.fit === 'center') {
      attrs.x = (width - imageWidth) / 2
      attrs.y = (height - imageHeight) / 2
      attrs.width = imageWidth
      attrs.height = imageHeight
    } else if (cfg.fit === 'adapt') {
      let widthScale = width / imageWidth
      let heightScale = height / imageHeight
      let scale = (widthScale <= heightScale) ? widthScale : heightScale
      attrs.width = imageWidth * scale
      attrs.height = imageHeight * scale
      attrs.x = (width - attrs.width) / 2
      attrs.y = (height - attrs.height) / 2
    }

    var bgImg = this.stage.find('.bgImg')[0]
    if (bgImg) {
      bgImg.setAttrs(attrs)
    } else {
      var node = new Konva.Image(attrs)
      layer.add(node)
    }

    layer.draw()
  }

  this.updateTitle = function(cfg) {
    let width = this.width
    let height = this.height
    var fontStyle = ''
    if (cfg.italic) {
      fontStyle += 'italic '
    }
    if (cfg.bold) {
      fontStyle += 'bold'
    }

    var attrs = {
      x: cfg.x,
      y: cfg.y,
      text: cfg.text,
      fontSize: cfg.fontSize,
      fontFamily: cfg.fontFamily,
      fontStyle: fontStyle,
      fill: cfg.color.hex,
      draggable: true,
      name: 'title'
    }
    let layer = this.getLayer()

    var title = this.stage.find('.title')[0]
    if (title) {
      title.setAttrs(attrs)
    } else {
      var node = new Konva.Text(attrs)
      node.on('dragend', function(e) {
        var position = node.position()
        cfg.x = position.x
        cfg.y = position.y
      })
      node.dragBoundFunc(function(pos) {
        let textWidth = this.getTextWidth()
        let textHeight = this.getTextHeight()
        let minX = 0
        let minY = 0
        let maxX = width - textWidth
        let maxY = height - textHeight
        var x = pos.x < minX ? minX : pos.x
        var y = pos.y < minY ? minY : pos.y
        x = x > maxX ? maxX : x
        y = y > maxY ? maxY : y
        return {
          x,
          y
        }
      })
      layer.add(node)
    }

    layer.draw()
  }

  /* 设置M X N布局（规则） */
  this.setMultiScreen = function(cfg) {
    let screenWidth = this.width / cfg.x
    let screenHeight = this.height / cfg.y
    let layer = this.getLayer()

    if (cfg.x > 1) {
      for (let i = 1; i < cfg.x; i++) {
        var node = new Konva.Rect({
          x: screenWidth * i - 3,
          y: 0,
          width: 3,
          height: this.height,
          fill: '#FFF'
        })
        layer.add(node)
      }
    }
    if (cfg.y > 1) {
      for (let i = 1; i < cfg.y; i++) {
        var node = new Konva.Rect({
          x: 0,
          y: screenHeight * i - 3,
          width: this.width,
          height: 3,
          fill: '#FFF'
        })
        layer.add(node)
      }
    }

    layer.draw()
  }

  //获取arr[0]到arr[index]的总高度/总宽度
  function getArrSumWidthOrHerght(arr, index){
    var sum = 0;
    for(var i = 0; i < index; i++) {
      sum += arr[i];
    }    
    return sum;    
  }

  /* 设置M X N布局 （非规则）*/
  this.setMultiScreenCustom = function(cfg) {
    /*---------------------------------------------------------------------------------------
    this.width: dom的实际总宽度（约1280px）
    this.height: dom的实际总高度（约670px）
    cfg.widths: 宽度数组
    cfg.heights：高度数组
    原理：在一块画布上画出几条小缝隙，就可以把画布切割为几个部分
    说明：区别于规则的布局，这个函数要从cfg.screen这个数组中把宽高一个一个画出来
    ----------------------------------------------------------------------------------------*/
    let screenWidth = this.width / getArrSumWidthOrHerght(cfg.widths, cfg.widths.length);
    let screenHeight = this.height / getArrSumWidthOrHerght(cfg.heights, cfg.heights.length);
    let layer = this.getLayer()
    
    if (cfg.x > 1) {
      for(var i = 1; i < cfg.widths.length; i++) {        
        var node = new Konva.Rect({
          x: getArrSumWidthOrHerght(cfg.widths, i) * screenWidth - 3,
          y: 0,
          width: 3,
          height: this.height,
          fill: '#FFF'
        })
        layer.add(node)
      }     
    }
    if (cfg.y > 1) {
      for(var i = 1; i < cfg.heights.length; i++) {
        var node = new Konva.Rect({
          x: 0,
          y: getArrSumWidthOrHerght(cfg.heights, i) * screenHeight - 3,
          width: this.width,
          height: 3,
          fill: '#FFF'
        })
        layer.add(node)
      }
    }

    layer.draw()
  }

  function updateBannerCfg(group, scale) {
    var banner = group.banner
    var image = group.find('Image')[0]
    var showRect = banner.showRect
    let x = group.x() + image.x()
    let y = group.y() + image.y()
    showRect.left = Math.round(x / scale)
    showRect.top = Math.round(y / scale)
    showRect.right = Math.round((x + image.width())  / scale)
    showRect.bottom = Math.round((y + image.height())  / scale) 
  }

  function updateAnchor(activeAnchor, scale) {
    var group = activeAnchor.getParent()

    var topLeft = group.find('.topLeft')[0]
    var topRight = group.find('.topRight')[0]
    var bottomRight = group.find('.bottomRight')[0]
    var bottomLeft = group.find('.bottomLeft')[0]
    var image = group.find('Image')[0]
    var rect = group.find('Rect')[0]
    var text = group.find('Text')[0]

    var anchorX = activeAnchor.getX()
    var anchorY = activeAnchor.getY()
    
    // update anchor positions
    switch (activeAnchor.getName()) {
      //不能超过对角的那个点
      case 'topLeft':
        var y = topLeft.getY() <= bottomRight.getY() - 24 ? topLeft.getY() : bottomRight.getY() - 24
        var x = topLeft.getX() <= bottomRight.getX() - 24 ? topLeft.getX() : bottomRight.getX() - 24      
        topLeft.setY(y)
        topRight.setY(y)
        topLeft.setX(x)
        bottomLeft.setX(x)
        break
      case 'topRight':
        var y = topRight.getY() <= bottomLeft.getY() - 24 ? topRight.getY() : bottomLeft.getY() - 24
        var x = topRight.getX() >= bottomLeft.getX() + 24 ? topRight.getX() : bottomLeft.getX() + 24
        topRight.setY(y)
        topLeft.setY(y)
        topRight.setX(x)
        bottomRight.setX(x)
        break
      case 'bottomRight':
        var y = bottomRight.getY()  >= topLeft.getY() + 24 ? bottomRight.getY() : topLeft.getY() + 24
        var x = bottomRight.getX() >= topLeft.getX() + 24 ? bottomRight.getX() : topLeft.getX() + 24
        bottomRight.setY(y)
        bottomLeft.setY(y)
        bottomRight.setX(x)
        topRight.setX(x)
        break
      case 'bottomLeft':
        var y = bottomLeft.getY() >= topRight.getY() + 24 ? bottomLeft.getY() : topRight.getY()+ 24
        var x = bottomLeft.getX() <= topRight.getX() - 24 ? bottomLeft.getX() : topRight.getX() - 24
        bottomLeft.setY(y)
        bottomRight.setY(y)
        bottomLeft.setX(x)
        topLeft.setX(x)
        break
    }

    image.position(topLeft.position())
    rect.position(topLeft.position())
    text.position(topLeft.position())

    var width = topRight.getX() - topLeft.getX()
    var height = bottomLeft.getY() - topLeft.getY()
    if (width && height) {
      image.width(width)
      image.height(height)
      rect.width(width)
      rect.height(height)
      text.width(width)
      setAlignv(group)
    }
    updateBannerCfg(group, scale)  
  }

  function addAnchor(group, realX, realY, scale, name) {
    var stage = group.getStage()
    var layer = group.getLayer()
    var x = realX * scale
    var y = realY * scale

    var anchor = new Konva.Circle({
      x: x,
      y: y,
      stroke: '#666',
      fill: '#ddd',
      strokeWidth: 2,
      radius: 8,
      name: name,
      draggable: true,
      dragOnTop: false
    })

    anchor.dragBoundFunc(function(pos) {
      let minX = 0
      let minY = 0
      let maxX = stage.width()
      let maxY = stage.height()
      var x = pos.x < minX ? minX : pos.x
      var y = pos.y < minY ? minY : pos.y
      x = x > maxX ? maxX : x
      y = y > maxY ? maxY : y
      return {
        x,
        y
      }
    }) 

    anchor.on('dragmove', function(evt) {
      if (evt.target === this) {
        updateAnchor(this, scale)
        layer.draw()
      }
    })
    anchor.on('mousedown touchstart', function() {
      group.setDraggable(false)
      this.moveToTop()
    })
    anchor.on('dragend', function() {
      group.setDraggable(true)
      //layer.draw()
      //规避改变大小后，group的drag bound失效问题
      this.off('mouseover mouseout')
      ebus.emit('reset-lcdbg')
    })
    // add hover styling
    anchor.on('mouseover', function() {
      var layer = this.getLayer()
      document.body.style.cursor = 'pointer'
      this.setStrokeWidth(4)
      layer.draw()
    })
    anchor.on('mouseout', function() {
      var layer = this.getLayer()
      document.body.style.cursor = 'default'
      this.setStrokeWidth(2)
      layer.draw()
    })

    group.add(anchor)
  }

  function setAlignv(group) {
    var banner = group.banner
    var image = group.find('Image')[0]
    var text = group.find('Text')[0]

    var offsetY = 0
    let totalHeight = image.height()
    if (banner.text.alignV === 'center') {
      offsetY = (totalHeight - text.height()) / 2
    } else if (banner.text.alignV === 'bottom') {
      offsetY = totalHeight - text.height()
    }
    text.y(image.y() + offsetY)
  }

  this.updateBanners = function(banners) {
    let stage = this.stage
    var groups = stage.find('.banner')
    groups.each(function(group) {
      group.destroy()
    })

    _.forEach(banners, function(banner) {
      this.addBanner(banner)
    }.bind(this))
  }

  this.measureText = function(attrs) {
    if (!this.context) {
      var canvas = document.createElement("canvas")
      var context = canvas.getContext('2d')
      this.context = context
    }

    this.context.font = `${attrs.fontSize}px ${attrs.fontFamily}`
    this.context.textAlign = attrs.align

    return this.context.measureText(attrs.text)
  }

  this.updateBannerText = function(group) {
    let banner = group.banner
    let showRect = banner.showRect
    let width = (showRect.right - showRect.left) * this.scale
    let textCfg = banner.text
    let fontSize = textCfg.fontSize * this.scale

    var attrs = {
      width: width,
      height: fontSize,
      text: textCfg.content,
      fontSize: fontSize,
      fontFamily: textCfg.fontName,
      fill: banner._tmp.color.hex,
      align: textCfg.align,
      visible: textCfg.show === 1
    }

    if (banner._tmp.preview) {
      var text = group.find('Text')[0]
      if (text) {
        text.setAttrs(attrs)
      } else {
        var node = new Konva.Text(attrs)
        group.add(node)
      }   
      setAlignv(group)
    }  

    banner._tmp.textWidth = this.measureText(attrs).width
  }

  this.setBannerBgVisible = function(group, visible) {
    let layer = this.getLayer()
    var rect = group.find('Rect')[0]
    if (rect) {
      rect.visible(visible)
      layer.draw()
    }
  }

  this.updateBannerBg = function(group) {
    let banner = group.banner
    let showRect = banner.showRect
    let background = banner.background
    let width = (showRect.right - showRect.left) * this.scale
    let height = (showRect.bottom - showRect.top) * this.scale

    var attrs = {
      width: width,
      height: height,
      fill: banner._tmp.bgColor.hex,
      opacity: background.opacity / 100,
      visible: false
    }

    if (background.show) {
      attrs.visible = true
    }

    var rect = group.find('Rect')[0]
    if (rect) {
      rect.setAttrs(attrs)
    } else {
      var node = new Konva.Rect(attrs)
      group.add(node)
    }     
  }

  this.updateBannerImage = function(group) {
    let banner = group.banner
    let showRect = banner.showRect
    let background = banner.background
    let width = (showRect.right - showRect.left) * this.scale
    let height = (showRect.bottom - showRect.top) * this.scale

    var attrs = {
      width: width,
      height: height
    }
    if (background.show) {
      attrs.image = banner._tmp.img
    }

    if (banner._tmp.preview) {
      attrs.stroke = '#444'      
    }

    var image = group.find('Image')[0]
    if (image) {
      image.setAttrs(attrs)
      if (!background.show) {
        image.setImage(null)
      }
    } else {
      var node = new Konva.Image(attrs)
      group.add(node)
    } 
  }

  this.updateBanner = function(index) {
    let stage = this.stage
    let layer = this.getLayer()
    var group = stage.find('.banner')[index]
    if (!group) {
      return
    }

    this.updateBannerBg(group)
    this.updateBannerImage(group)
    this.updateBannerText(group)
    layer.draw()
  }

  function addBannerGroup(stage, banner, scale) {
    let showRect = banner.showRect

    var group = new Konva.Group({
      x: showRect.left * scale,
      y: showRect.top * scale,
      name: 'banner',
      draggable: true,
      dragBoundFunc: function(pos) {
        var stage = this.getStage()
        let totalWidth = stage.width()
        let totalHeight = stage.height()
        var image = this.find('Image')[0]
        let rectWidth = image.width()
        let rectHeight = image.height()
        var x = Math.max(pos.x, 0)
        var y = Math.max(pos.y, 0)
        x = Math.min(x, totalWidth - rectWidth)
        y = Math.min(y, totalHeight - rectHeight)
        return {x, y}
      }
    })

    group.banner = banner
    group.on('dragmove', function(evt) {
      if (evt.target === this) {
        updateBannerCfg(this, scale)
      }
    })

    group.on('mousedown', function(evt) {
      let banner = this.banner
      banner._tmp.onSelect && banner._tmp.onSelect()
    })

    return group
  }

  this.addAnchors = function(group) {
    let banner = group.banner
    let showRect = banner.showRect

    let relX = showRect.right - showRect.left
    let relY = showRect.bottom - showRect.top
    addAnchor(group, 0, 0, this.scale, 'topLeft')
    addAnchor(group, relX, 0, this.scale, 'topRight')
    addAnchor(group, relX, relY, this.scale, 'bottomRight')
    addAnchor(group, 0, relY, this.scale, 'bottomLeft') 
  }

  this.addBanner = function(banner) {
    let layer = this.getLayer()
    let stage = this.stage

    var group = addBannerGroup(stage, banner, this.scale)
    layer.add(group)
    this.updateBannerBg(group)
    this.updateBannerImage(group)
    this.updateBannerText(group)
    if (banner._tmp.preview) {
      this.addAnchors(group)
    }
    layer.draw()
  }

  this.uninit = function() {
    this.stage && this.stage.destroy()
  }
}

function isLineOverlap(x, xLen, y, yLen) {
  let xStart = Math.min(x, x + xLen)
  let xEnd = Math.max(x, x + xLen)
  let yStart = Math.min(y, y + yLen)
  let yEnd = Math.max(y, y + yLen)
  let cStart = Math.max(xStart, yStart)
  let cEnd = Math.min(xEnd, yEnd)

  return cStart < cEnd
}

function isRectOverlap(rect1, rect2) {
  return isLineOverlap(rect1.x, rect1.width, rect2.x, rect2.width) 
    && isLineOverlap(rect1.y, rect1.height, rect2.y, rect2.height)
}

export function LcdwallArea() {
  function delArea(area, grids) {
    _.forEach(grids, (item) => {
      if (area === item.userdata.belongTo) {
        item.userdata.belongTo = null
      }
    })
    area.userdata.areaName.destroy()
    area.userdata.areaName = undefined
    area.destroy()
  }

  function addArea(layer, areaParams) {
    var grids = areaParams.grids
    let rect = areaParams.rect
    let areaCfg = areaParams.areaCfg
    var area = new Konva.Rect({
      x: rect.x,
      y: rect.y,
      width: rect.width,
      height: rect.height,
      fill: 'yellow',
      stroke: 'red',
      strokeWidth: 3,
      opacity: 0.5
    })
    var areaName = new Konva.Text({
      x: rect.x,
      y: rect.y + (rect.height * 1 / 3),
      width: rect.width,
      text: areaCfg.name,
      fontSize: 15,
      fontFamily: 'Calibri',
      fontStyle: 'bold',
      fill: 'red',
      align: 'center',
      listening: false
    });
    _.forEach(grids, (item) => {
      item.userdata.belongTo = area
    })
    area.userdata = {
      type: 'area',
      areaCfg: areaParams.areaCfg,
      areaName: areaName
    }
    area.on('dblclick', function(e) {
      delArea(e.target, grids)
      layer.draw()
    })
    layer.add(area)
    layer.add(areaName)
  }

  function getGrids(layer) {
    let children = layer.getChildren(function(node) {
      return node.userdata && node.userdata.type === 'screen'
    })

    return children
  }

  function getAreas(layer) {
    let children = layer.getChildren(function(node) {
      return node.userdata && node.userdata.type === 'area'
    })

    return children
  }

  function getAreaParamsWithGrids(grids, opt) {
    let orderedGrids = _.orderBy(grids, ['userdata.screenX', 'userdata.screenY'], ['asc', 'asc'])
    let startGrid = orderedGrids[0]
    let endGrid = orderedGrids[orderedGrids.length - 1]
    let start = startGrid.getAttrs()
    let endAttrs = endGrid.getAttrs()
    let end = {
      x: endAttrs.x + endAttrs.width,
      y: endAttrs.y + endAttrs.height,
    }
    var areaParams = {
      grids,
      rect: {
        x: start.x,
        y: start.y,
        width: end.x - start.x,
        height: end.y - start.y,
      }
    }
    if (opt.areaCfg) {
      areaParams.areaCfg = opt.areaCfg
    } else {
      areaParams.areaCfg = {
        name: opt.name,
        _field: opt.name,
        startScreenX: startGrid.userdata.screenX,
        startScreenY: startGrid.userdata.screenY,
        multiScreenX: endGrid.userdata.screenX - startGrid.userdata.screenX + 1,
        multiScreenY: endGrid.userdata.screenY - startGrid.userdata.screenY + 1,
      }
    }

    return areaParams
  }

  function selectGrids(layer, select, areaIndex) {
    var isConflict = false
    var selectedGrids = []
    let grids = getGrids(layer)

    _.forEach(grids, (item) => {
      var fillColor = ''
      if (isRectOverlap(item.getAttrs(), select.getAttrs())) {
        selectedGrids.push(item)
        if (item.userdata.belongTo !== null) {
          fillColor = 'red'
          isConflict = true
        } else {
          fillColor = 'green'
        }        
      }
      if (areaIndex > 0) {
        fillColor = ''
      }
      item.setAttrs({
        fill: fillColor
      })
    })
    if (areaIndex > 0 && !isConflict) {
      let areaParams = getAreaParamsWithGrids(selectedGrids, {
        name: 'area' + areaIndex
      })
      addArea(layer, areaParams)
    }
  }

  function isGridInArea(gridScreen, areaCfg) {
    return _.inRange(gridScreen.screenX,
      areaCfg.startScreenX,
      areaCfg.startScreenX + areaCfg.multiScreenX) && _.inRange(gridScreen.screenY,
      areaCfg.startScreenY,
      areaCfg.startScreenY + areaCfg.multiScreenY)
  }

  function getAreaGrids(layer, areaCfg) {
    let grids = getGrids(layer)
    return _.filter(grids, (item) => {
      return isGridInArea(item.userdata, areaCfg)
    })
  }

  function drawArea(layer, areaCfg) {
    var areaGrids = getAreaGrids(layer, areaCfg)
    let areaParams = getAreaParamsWithGrids(areaGrids, {
      areaCfg
    })
    addArea(layer, areaParams)
  }

  this.init = function(container, cfg) {
    if (this.stage) {
      this.areaIndex = 1
      this.select = undefined
      this.dftLayer = undefined
      this.stage.destroy()
    }

    this.areaIndex = 1

    this.stage = new Konva.Stage({
      container: container,
      width: cfg.width,
      height: cfg.height
    })

    let layer = new Konva.Layer()
    layer.on('mousedown', function(e) {
      if (!this.select) {
        var attrs = {
          x: e.evt.offsetX,
          y: e.evt.offsetY,
          width: 0,
          height: 0,
          stroke: 'red'
        }
        this.select = new Konva.Rect(attrs)
        layer.add(this.select)        
      }
    }.bind(this))
    layer.on('mousemove', function(e) {
      if (this.select) {
        this.select.size({
          width: e.evt.offsetX - this.select.getAttr('x'),
          height: e.evt.offsetY - this.select.getAttr('y'),
        })
        selectGrids(layer, this.select, -1)
        layer.draw()
      }
    }.bind(this))
    layer.on('mouseleave', function(e) {
      layer.fire('mouseup')
    }.bind(this))
    layer.on('mouseup', function(e) {
      if (this.select) {
        let attrs = this.select.getAttrs()
        if (attrs.width !== 0 && attrs.height !== 0) {
          selectGrids(layer, this.select, this.areaIndex)
          this.areaIndex++
        } else {
          selectGrids(layer, this.select, -1)
        }
        this.select.destroy()
        layer.draw()
        this.select = undefined
      }
    }.bind(this))

    this.width = cfg.width
    this.height = cfg.height
    this.stage.add(layer)
    this.dftLayer = layer
  }

  this.drawAreas = function(cfgOfAreas) {
    let layer = this.dftLayer
    let grids = getGrids(layer)
    let areas = getAreas(layer)
    _.forEach(areas, (item) => {
      delArea(item, grids)
    })
    _.forEach(cfgOfAreas, (item) => {
      drawArea(layer, item)
    })
    layer.draw()
  }

  this.getCfgOfAreas = function() {
    let layer = this.dftLayer
    let areas = getAreas(layer)
    return _.map(areas, (item) => {
      return item.userdata.areaCfg
    })
  }

  this.drawGrid = function(cfg) {
    let screenWidth = this.width * 0.99 / cfg.x
    let screenHeight = this.height * 0.99 / cfg.y
    var rectAttrs = {
      x: 0,
      y: 0,
      width: screenWidth - 1,
      height: screenHeight - 1,
      stroke: '#AAA',
      strokeWidth: 2
    }
    var textAttrs = {
      x: 0,
      y: 0,
      text: ''
    }
    let layer = this.dftLayer

    for (var i = 0; i < cfg.x; i++) {
      for (var j = 0; j < cfg.y; j++) {
        textAttrs.x = rectAttrs.x = screenWidth * i + this.width * 0.01
        textAttrs.y = rectAttrs.y = screenHeight * j + this.height * 0.01
        var rect = new Konva.Rect(rectAttrs)
        rect.userdata = {
          type: 'screen',
          screenX: i,
          screenY: j,
          belongTo: null
        }
        layer.add(rect)
        textAttrs.text = `(${i + 1}, ${j + 1})`
        var text = new Konva.Text(textAttrs)
        layer.add(text)
      }
    }

    layer.draw()
  }

  this.uninit = function() {
    this.stage && this.stage.destroy()
  }
}

export function getMyCanvas() {
  var canvas = document.getElementById("myCanvas");
  var ctx = canvas.getContext("2d");
  return ctx;
}
